﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Linq;
using System.Text;
using GroupCheer.FBGraphAPI;

namespace GroupCheer.FBGraphAPI.Core
{
    internal class AsyncNetwork
    {
        public delegate void ExecuteCompleted(string ResponseData);
        public delegate void ExecuteStateChanged(string StateText);

        public static void MakeHttpPost(string RequestUrl)
        {
            MakeHttpPost(RequestUrl, new Dictionary<string, string>());
        }

        public static void MakeHttpPost(string RequestUrl, Dictionary<string, string> HttpPostData)
        {
            HttpWebRequest request = WebRequest.Create(RequestUrl) as HttpWebRequest;
            HttpWebResponse response = null;

            StreamReader sr = null;
            StreamWriter sw = null;

            try
            {
                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Initializing HTTP connection." });

                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";

                StringBuilder sb = new StringBuilder();

                sb.Append("access_token=" + FBGraphAPIConfiguration.FBValidAccessToken);

                if (HttpPostData != null && HttpPostData.Count > 0)
                {
                    foreach (KeyValuePair<string, string> postItem in HttpPostData)
                    {
                        if (sb.Length == 0)
                            sb.Append(string.Format("{0}={1}", postItem.Key, postItem.Value));
                        else
                            sb.Append(string.Format("&{0}={1}", postItem.Key, postItem.Value));
                    }
                }

                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Initializing HTTP Stream." });

                request.BeginGetRequestStream((arGetRequestStream) =>
                    {

                        Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Write data into Stream." });

                        sw = new StreamWriter(request.EndGetRequestStream(arGetRequestStream));
                        sw.Write(sb.ToString());
                        sw.Close();

                        Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Make the communication." });

                        request.BeginGetResponse((arGetResponse) =>
                            {
                                try
                                {
                                    Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "HTTP Response received." });

                                    response = request.EndGetResponse(arGetResponse) as HttpWebResponse;

                                    sr = new StreamReader(response.GetResponseStream());
                                    string responseData = sr.ReadToEnd();
                                    sr.Close();

                                    response.Close();

                                    Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = true, EventData = responseData });
                                }
                                catch (WebException we)
                                {
                                    Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
                                }
                                catch (Exception e)
                                {
                                    Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
                                }
                            },
                            request);

                    },
                    request);
            }
            catch (WebException we)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
            }
            catch (Exception e)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
            }
        }

        public static void MakeHttpPost(string RequestUrl, Dictionary<string, string> HttpPostData, PostFileData FileUploadData)
        {
            HttpWebRequest request = WebRequest.Create(RequestUrl) as HttpWebRequest;
            HttpWebResponse response = null;

            StreamReader sr = null;
            string boundary = "FBGraphAPIClient" + DateTime.Now.Ticks.ToString();

            try
            {
                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Initializing HTTP connection." });

                request.Method = "POST";
                request.ContentType = "multipart/form-data; boundary=----" + boundary;

                byte[] multipartPostData = Helpers.BuildMultipartPostData(boundary, HttpPostData, FileUploadData);

                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Initializing HTTP Stream." });

                request.BeginGetRequestStream((arGetRequestStream) =>
                {

                    Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Write data into Stream." });

                    BinaryWriter bw = new BinaryWriter(request.EndGetRequestStream(arGetRequestStream));
                    bw.Write(multipartPostData);
                    bw.Close();

                    Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Make the communication." });

                    request.BeginGetResponse((arGetResponse) =>
                    {
                        try
                        {
                            Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "HTTP Response received." });

                            response = request.EndGetResponse(arGetResponse) as HttpWebResponse;

                            sr = new StreamReader(response.GetResponseStream());
                            string responseData = sr.ReadToEnd();
                            sr.Close();

                            response.Close();

                            Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = true, EventData = responseData });
                        }
                        catch (WebException we)
                        {
                            Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
                        }
                        catch (Exception e)
                        {
                            Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
                        }
                    },
                    request);
                },
                request);
            }
            catch (WebException we)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
            }
            catch (Exception e)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
            }
        }

        public static void MakeHttpGet(string RequestUrl)
        {
            HttpWebRequest request = WebRequest.Create(RequestUrl) as HttpWebRequest;
            HttpWebResponse response = null;

            StreamReader sr = null;

            try
            {
                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Initializing HTTP connection." });

                request.Method = "GET";

                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Make the communication." });

                request.BeginGetResponse((arGetResponse) =>
                {
                    try
                    {
                        Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "HTTP Response received." });

                        response = request.EndGetResponse(arGetResponse) as HttpWebResponse;

                        sr = new StreamReader(response.GetResponseStream());
                        string responseData = sr.ReadToEnd();
                        sr.Close();

                        response.Close();

                        Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = true, EventData = responseData });
                    }
                    catch (WebException we)
                    {
                        Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
                    }
                    catch (Exception e)
                    {
                        Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
                    }
                },
                request);
            }
            catch (WebException we)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
            }
            catch (Exception e)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
            }
        }

        public static void MakeHttpDelete(string RequestUrl)
        {
            HttpWebRequest request = WebRequest.Create(RequestUrl) as HttpWebRequest;
            HttpWebResponse response = null;

            StreamReader sr = null;

            try
            {
                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Initializing HTTP connection." });

                request.Method = "DELETE";

                Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "Make the communication." });

                request.BeginGetResponse((arGetResponse) =>
                {
                    try
                    {
                        Global.EventSink.OnExecuteStateChanged(null, new FBGraphAPIEventStateChangedEventArgs() { EventData = "HTTP Response received." });

                        response = request.EndGetResponse(arGetResponse) as HttpWebResponse;

                        sr = new StreamReader(response.GetResponseStream());
                        string responseData = sr.ReadToEnd();
                        sr.Close();

                        response.Close();

                        Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = true, EventData = responseData });
                    }
                    catch (WebException we)
                    {
                        Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
                    }
                    catch (Exception e)
                    {
                        Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
                    }
                },
                request);
            }
            catch (WebException we)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = new FBGraphAPIException((we.Response as HttpWebResponse)) });
            }
            catch (Exception e)
            {
                Global.EventSink.OnExecuteCompleted(null, new FBGraphAPIEventCompletedEventArgs() { isCompleted = false, LastException = e });
            }
        }
    }
}
